package com.spring.bucks.config;

import com.alibaba.druid.filter.FilterChain;
import com.alibaba.druid.filter.FilterEventAdapter;
import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.JdbcConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.sql.SQLException;
import java.util.List;

/**
 * @author 超
 * Create by fengc on  2022/8/29 23:35
 * todo sql拼接的参数配置
 */
@Slf4j
public class SplicingLogFilter extends FilterEventAdapter {

    @Override
    public boolean preparedStatement_execute(FilterChain chain, PreparedStatementProxy statement) throws SQLException {
        log.info("进入了方法SplicingLogFilter.preparedStatement_execute().............");
        try {
            List<SQLStatement> statementList = SQLUtils.parseStatements(statement.getSql(), JdbcConstants.MYSQL);
            MySqlSchemaStatVisitor statVisitor = new MySqlSchemaStatVisitor();
            if (!CollectionUtils.isEmpty(statementList)) {
                for (SQLStatement sqlStatement : statementList) {
                    sqlStatement.accept(statVisitor);
                    for (TableStat.Condition condition : statVisitor.getConditions()) {
                        if (CollectionUtils.isEmpty(condition.getValues()) || condition.getValues().size() < 3) {
                            continue;
                        }
                        throw new SQLException(String.format("参数【%s】入参个数：%s,超过10个条限制。具体SQL：%s",condition.getColumn(),
                                condition.getValues().size(),sqlStatement));
                    }
                 }
            }
        } catch (SQLException e) {
            log.info("ConnectionLogFilter：执行 SQL 规则过滤器校验不通过！", e);
        } catch (Exception e) {
            log.error("ConnectionLogFilter：执行 SQL 规则过滤器失败！", e);
        }
        return super.preparedStatement_execute(chain, statement);
    }
}
